import configparser
import json
import unittest
import os

from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.action_chains import ActionBuilder
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.actions import interaction
from appium import webdriver
from appium.options.android import UiAutomator2Options
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

appium_server_url = 'http://127.0.0.1:4723'
class ConfigHandler:
    def __init__(self):
        # 获取 config.ini 绝对路径，适配项目结构
        config_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "config", "config.ini")
        self.config = configparser.ConfigParser()
        self.config.optionxform = str # 维持原始键名大小写
        self.config.read(config_path)
    def _str_to_bool(self,z):
        """纯bool处理函数名前面加_只能在类的内部使用"""
        return z.strip().lower() in ('1','yes','true','on')
    def read(self,section,key):
        """读取指定扇区的指定键的值"""
        return  self.config.get(section,key)
    def read_section(self,section):
         """读取指定扇区的所有键值对"""
         options=self.config.items(section)
         dct={}
         for key,value in options:
             if self._str_to_bool(value):
                 dct[key]=True
             else:
                 dct[key]=value
         return dct
    def read_capabilities(self,application):
        """获取app页面信息"""
        # 先读需要的页面的app信息
        app_dict=self.read_section(application)
        # 再读取基本的app信息
        base_dict=self.read_section("base-capabilities")
        # 合并并返回
        app_dict.update(base_dict)
        return  app_dict
def open_app(capabilities):
    """打开app页面"""
    return webdriver.Remote(appium_server_url, options=UiAutomator2Options().load_capabilities(capabilities))
class Slide:
    def __init__(self,driver):
        self.driver=driver
        self.x,self.y=self.driver.get_window_size().values()
    def up(self):
        start_x=end_x=self.x*0.5
        start_y=self.y*0.9
        end_y = self.y * 0.2
        self.driver.swipe(start_x=start_x,end_x=end_x,start_y=start_y,end_y=end_y,duration=2000)
    def down(self):
        start_x = end_x = self.x * 0.5
        start_y = self.y * 0.2
        end_y = self.y * 0.9
        self.driver.swipe(start_x=start_x, end_x=end_x, start_y=start_y, end_y=end_y, duration=2000)
    def left(self):
        start_y = end_y = self.x * 0.5
        start_x = self.x * 0.2
        end_x = self.x * 0.9
        self.driver.swipe(start_x=start_x, end_x=end_x, start_y=start_y, end_y=end_y, duration=2000)
    def right(self):
        start_y = end_y = self.x * 0.5
        start_x = self.x * 0.9
        end_x = self.x * 0.2
        self.driver.swipe(start_x=start_x, end_x=end_x, start_y=start_y, end_y=end_y, duration=2000)
class EnhancedActions:
    def __init__(self, driver):
        self.driver = driver
    def drag_and_drop_and_scroll(self,
                                 start_el: WebElement,
                                 end_el: WebElement,
                                 pause= 2,
                                 duration=2):
        """拖动元素并滚动，包含暂停和持续时间设置"""
        touch_input = PointerInput(interaction.POINTER_TOUCH, 'touch')
        actions = ActionChains(self.driver)
        actions.w3c_actions = ActionBuilder(self.driver, mouse=touch_input)
        actions.w3c_actions.pointer_action.move_to(start_el)
        actions.w3c_actions.pointer_action.pointer_down()
        actions.w3c_actions = ActionBuilder( self.driver,mouse=touch_input,duration=int(duration * 1000))
        actions.w3c_actions.pointer_action.pause(pause)
        actions.w3c_actions.pointer_action.move_to(end_el)
        actions.w3c_actions.pointer_action.release()
        actions.perform()
        return self
    def test_unlock(self,secrets):
        # 用字典的格式把解锁键位存起来
        points = {'1': (150, 1284), '2': (450, 1284), '3': (750, 1284),
                  '4': (150, 1384), '5': (450, 1384), '6': (666, 1384),
                  '7': (150, 1484), '8': (450, 1484), '9': (666, 1484),
                  '0':(450,1584)}
        # 把输入的数据表示出来
        secrets=str(secrets)
        touch_input=PointerInput(interaction.POINTER_TOUCH,'touch')
        actions=ActionChains(self.driver)
        actions.w3c_actions=ActionBuilder(self.driver,mouse=touch_input)
        for point in secrets:
            x,y=points.get(point)
            actions.w3c_actions.pointer_action.pause(1)
            actions.w3c_actions.pointer_action.move_to_location(x,y)
            actions.w3c_actions.pointer_action.pointer_down()
            actions.w3c_actions.pointer_action.pointer_up()
            actions.perform()

def wait_for_toast(driver, text, timeout=10):
    toast_xpath = f'//android.widget.Toast[@text="{text}"]'
    try:
        toast = WebDriverWait(driver, timeout).until(
            EC.presence_of_element_located((AppiumBy.XPATH, toast_xpath))
        )
        return toast.text
    except:
        raise AssertionError(f'未检测到 Toast："{text}"')